# -*- coding: utf-8 -*-
import json
import copy
import random
import logging

from common import orm
from common.campaign.model.wheel import *
from common.coupon.db import award_coupon_in_transaction

from common.utils.decorator import sql_wrapper
from common.utils.respcode import StatusCode
from common.utils import exceptions as err


_LOGGER = logging.getLogger('campaign')


def calc_added_times(double_bit, new_status, current_status=0, init=False):
    add_normal_times = 0
    add_double_times = 0
    added_status = new_status - current_status
    if added_status < 0:
        _LOGGER.warn('calc_added_times, added_status lt 0')
        return add_normal_times, add_double_times
    for task_conf in TASK_CONF:
        if added_status & task_conf['bit']:
            if task_conf['bit'] == double_bit:
                add_double_times += task_conf['add_times']
            else:
                add_normal_times += task_conf['add_times']
    if init:
        # 每日默认加一次
        add_normal_times += 1
    if new_status == 255 and added_status > 0:
        add_double_times += 1
    return add_normal_times, add_double_times


@sql_wrapper
def get_wheel(user_id, date_str):
    return FortuneWheel.query.filter(FortuneWheel.user_id == user_id
        ).filter(FortuneWheel.date == date_str).with_lockmode('update').first()


@sql_wrapper
def fresh_wheel(user_id, date_str, new_status, double_bit=0):
    item = FortuneWheel.query.filter(FortuneWheel.user_id == user_id
        ).filter(FortuneWheel.date == date_str).with_lockmode('update').first()
    if not item:
        item = FortuneWheel()
        item.user_id = user_id
        item.date = date_str
        item.apply_normal_times = 0
        item.apply_double_times = 0
        item.task_status = new_status
        add_normal_times, add_double_times = calc_added_times(double_bit, new_status,
            init=True)
        item.left_normal_times = add_normal_times
        item.left_double_times = add_double_times
        item.save()
    else:
        add_normal_times, add_double_times = calc_added_times(double_bit, new_status,
            current_status=item.task_status)
        item.left_normal_times += add_normal_times
        item.left_double_times += add_double_times
        item.task_status = new_status
        item.save()
    if item.left_double_times > 3:
        _LOGGER.warn('fresh_wheel, left_double_times gt 3')
    return item


@sql_wrapper
def play_wheel(user_id, date_str, award_index):
    item = FortuneWheel.query.filter(FortuneWheel.user_id == user_id
        ).filter(FortuneWheel.date == date_str).with_lockmode('update').first()
    if not item:
        raise err.ResourceInsufficient('reach limit', status=StatusCode.REACH_LIMIT)
    elif item.left_normal_times <= 0 and item.left_double_times <= 0:
        raise err.ResourceInsufficient('reach limit', status=StatusCode.REACH_LIMIT)
    elif item.left_normal_times > 0:
        item.left_normal_times -= 1
        item.apply_normal_times += 1
        is_double = 0
    else:
        item.left_double_times -= 1
        item.apply_double_times += 1
        is_double = 1
    item.save(auto_commit=False)
    award_item = FortuneWheelAward()
    award_item.user_id = user_id
    award_item.date = date_str
    award_item.is_double = is_double
    award_item.award_index = award_index
    award_item.status = 4
    coupon_tid = random.choice(AWARD_RATIO[award_index]['tid'])
    award_coupon_in_transaction(user_id, coupon_tid, coupon_from=u'幸运抽奖')
    award_item.save(auto_commit=False)
    orm.session.commit()
    return award_item


@sql_wrapper
def get_award_timeline():
    return FortuneWheelAward.query.order_by(FortuneWheelAward.created_at.desc()).limit(10).all()


@sql_wrapper
def get_user_award(user_id, limit=0, offset=0):
    query = FortuneWheelAward.query.filter(FortuneWheelAward.user_id == user_id)
    query = query.order_by(FortuneWheelAward.updated_at.desc())
    if limit > 0:
        query = query.limit(limit)
    if offset > 0:
        query = query.offset(offset)
    return query.all()
